﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevExpress.Skins;
using DevExpress.LookAndFeel;
using DevExpress.UserSkins;
using DevExpress.XtraEditors;
using DevExpress.XtraCharts;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Layout;

namespace RAMain
{
    public partial class Form1 : XtraForm
    {
        private void SetBingdingSource()
        {
            bindingSourceProducts.DataSource = this.dataSetRA;
            bindingSourceProducts.DataMember = "Products";

            bindingSourceOrderStatus.DataSource = this.dataSetRA;
            bindingSourceOrderStatus.DataMember = "OrderStatus";

            bindingSourceEmployees.DataSource = this.dataSetRA;
            bindingSourceEmployees.DataMember = "Employees";

            bindingSourceRoles.DataSource = this.dataSetRA;
            bindingSourceRoles.DataMember = "EmployeeRole";

            bindingSourceCategories.DataSource = this.dataSetRA;
            bindingSourceCategories.DataMember = "Categories";

            bindingSourceTables.DataSource = this.dataSetRA;
            bindingSourceTables.DataMember = "Tables";

        }

        private void SetEvent()
        {
            foreach (DataTable dt in dataSetRA.Tables)
            {
                dt.RowDeleted += new DataRowChangeEventHandler(dt_RowDeleted);

            }            
        }

        void dt_RowDeleted(object sender, DataRowChangeEventArgs e)
        {
            //throw new NotImplementedException();
            DataTable dt = sender as DataTable;
            if (dt.TableName == "Sessions")
            {
                DeleteASession((int)((RADB.DataSetRA.SessionsRow)e.Row)["ID", DataRowVersion.Original]);
            }            
            commitTables(dataSetRA, dt.TableName);
        }

        private void LoadData()
        {
            tableAdapters.Add("Categories", categoriesTableAdapter);
            categoriesTableAdapter.Fill(dataSetRA.Categories);
            tableAdapters.Add("CleanRequests", cleanRequestsTableAdapter);
            cleanRequestsTableAdapter.Fill(dataSetRA.CleanRequests);
            //tableAdapters.Add("EmployeeRole", employeeRoleTableAdapter);
            //employeeRoleTableAdapter.Fill(dataSetRA.EmployeeRole);
            //tableAdapters.Add("Employees", employeesTableAdapter);
            //employeesTableAdapter.Fill(dataSetRA.Employees);
            tableAdapters.Add("TablesStatus", tableStatusTableAdapter);
            tableStatusTableAdapter.Fill(dataSetRA.TableStatus);
            tableAdapters.Add("Tables", tablesTableAdapter);
            tablesTableAdapter.Fill(dataSetRA._Tables);
            tableAdapters.Add("Sessions", sessionsTableAdapter);
            sessionsTableAdapter.Fill(dataSetRA.Sessions);
            tableAdapters.Add("OrderStatus", orderStatusTableAdapter);
            orderStatusTableAdapter.Fill(dataSetRA.OrderStatus);
            tableAdapters.Add("OrderItems", orderItemsTableAdapter);
            orderItemsTableAdapter.Fill(dataSetRA.OrderItems);
            tableAdapters.Add("Products", productsTableAdapter);
            productsTableAdapter.Fill(dataSetRA.Products);
            tableAdapters.Add("Reserved", reservedPeriodsTableAdapter);
            reservedPeriodsTableAdapter.Fill(dataSetRA.ReservedPeriods);

        }

        public static void commitTables(RADB.DataSetRA dataSet, string tableName)
        {
            try
            {
                switch (tableName)
                {
                    case "Categories":
                        ((RADB.DataSetRATableAdapters.CategoriesTableAdapter)(tableAdapters["Categories"])).Update(dataSet);
                        break;
                    case "CleanRequests":
                        ((RADB.DataSetRATableAdapters.CleanRequestsTableAdapter)(tableAdapters["CleanRequests"])).Update(dataSet);
                        break;
                    case "EmployeeRole":
                        ((RADB.DataSetRATableAdapters.EmployeeRoleTableAdapter)(tableAdapters["EmployeeRole"])).Update(dataSet);
                        break;
                    case "Employees":
                        ((RADB.DataSetRATableAdapters.EmployeesTableAdapter)(tableAdapters["Employees"])).Update(dataSet);
                        break;
                    case "OrderItems":
                        ((RADB.DataSetRATableAdapters.OrderItemsTableAdapter)(tableAdapters["OrderItems"])).Update(dataSet);
                        break;
                    case "OrderStatus":
                        ((RADB.DataSetRATableAdapters.OrderStatusTableAdapter)(tableAdapters["OrderStatus"])).Update(dataSet);
                        break;
                    case "Products":
                        ((RADB.DataSetRATableAdapters.ProductsTableAdapter)(tableAdapters["Products"])).Update(dataSet);
                        break;
                    case "ReservedPeriods":
                        ((RADB.DataSetRATableAdapters.ReservedPeriodsTableAdapter)(tableAdapters["ReservedPeriods"])).Update(dataSet);
                        break;
                    case "Sessions":
                        ((RADB.DataSetRATableAdapters.OrderItemsTableAdapter)(tableAdapters["OrderItems"])).Update(dataSet);
                        ((RADB.DataSetRATableAdapters.SessionsTableAdapter)(tableAdapters["Sessions"])).Update(dataSet);
                        break;
                    case "Tables":
                        ((RADB.DataSetRATableAdapters.TablesTableAdapter)(tableAdapters["Tables"])).Update(dataSet);
                        break;
                    case "TableStatus":
                        ((RADB.DataSetRATableAdapters.TableStatusTableAdapter)(tableAdapters["TableStatus"])).Update(dataSet);
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                dataSet.RejectChanges();
            }
        }

        private void DeleteASession(int id)
        {
            DataRow[] rows = dataSetRA.OrderItems.Select("Session = " + id);
            foreach (DataRow row in rows)
            {
                row.Delete();
            }
        }

        private int CheckPassword(string user, string pass)
        {
            foreach (RADB.DataSetRA.EmployeesRow item in dataSetRA.Employees)
            {
                if (string.Compare(user, item.EmployeeCode, true) == 0 && pass == item.Pass)
                {
                    return item.Role;
                }
            }
            return 0;
        }

        private void Login()
        {
            var fLogin = new LoginDialog();
            int login = 0;
            bool isManager = false;

            while (!isManager)
            {
                if (!fLogin.getLogin())
                {
                    Application.ExitThread();
                    return;
                }
                login = CheckPassword(fLogin.UserName, fLogin.Password);
                if (login != 0)
                    isManager = string.Compare(dataSetRA.EmployeeRole.FindByID(login).RoleName, "manager", true) == 0;
            }

            SetRight(true);
        }

        private void SetRight(bool isManager)
        {
            tablesManagement.IsManager = isManager;
            gridViewEmployees.OptionsBehavior.Editable = isManager;
            layoutViewMenu.OptionsBehavior.Editable = isManager;
        }

        private int[] patronStatisticsByDay(DateTime start, DateTime finish)
        {
            
                if (start > finish)
                    return null;
                else
                {
                    int[] result = new int[(finish.Date - start.Date).Days + 1];
                    foreach (RADB.DataSetRA.SessionsRow item in dataSetRA.Sessions.Rows)
                    {
                        if (item.StartTime.Date >= start.Date && item.StartTime.Date <= finish.Date)
                        {
                            result[(item.StartTime.Date - start.Date).Days]++;
                        }
                    }

                    return result;
                }
            
            
        }

        private double[] patronStatisticsByHours(DateTime start, DateTime finish)
        {

           
                if (start > finish)
                    return null;
                else
                {
                    int numOfDay = (finish.Date - start.Date).Days + 1;
                    int[,] tmp = new int[numOfDay, 24];

                    foreach (RADB.DataSetRA.SessionsRow item in dataSetRA.Sessions.Rows)
                    {
                        if (item.StartTime.Date >= start.Date && item.StartTime.Date <= finish.Date)
                        {

                            tmp[(item.StartTime.Date - start.Date).Days, item.StartTime.Hour]++;
                        }
                    }
                    double[] result = new double[24];
                    for (int i = 0; i < (24); i++)
                    {
                        int count = 0;
                        for (int j = 0; j < numOfDay; j++)
                        {
                            count += tmp[j, i];
                        }
                        result[i] = (double)count / numOfDay;
                    }

                    return result;
                }
                  
        }

        private double[] RevenueStatisticsByDay(DateTime start, DateTime finish)
        {
            
                if (start > finish)
                    return null;
                else
                {
                    double[] result = new double[(finish.Date - start.Date).Days + 1];

                    foreach (RADB.DataSetRA.OrderItemsRow item in dataSetRA.OrderItems.Rows)
                    {
                        if (item.PlacingTime.Date >= start.Date && item.PlacingTime.Date <= finish.Date)
                        {
                            result[(item.PlacingTime.Date - start.Date).Days] += (double)item.RealToTal;
                        }
                    }

                    return result;
                }
            
        }

        private double[] RevenueStatisticsByHours(DateTime start, DateTime finish)
        {
            

                if (start > finish)
                    return null;
                else
                {
                    int numOfDay = (finish.Date - start.Date).Days + 1;
                    double[,] tmp = new double[numOfDay, 24];

                    foreach (RADB.DataSetRA.OrderItemsRow item in dataSetRA.OrderItems.Rows)
                    {
                        if (item.PlacingTime.Date >= start.Date && item.PlacingTime.Date <= finish.Date)
                        {

                            tmp[(item.PlacingTime.Date - start.Date).Days, item.PlacingTime.Hour] += (double)item.RealToTal;
                        }
                    }
                    double[] result = new double[24];
                    for (int i = 0; i < (24); i++)
                    {
                        double count = 0;
                        for (int j = 0; j < numOfDay; j++)
                        {
                            count += tmp[j, i];
                        }
                        result[i] = count / numOfDay;
                    }

                    return result;
                }
           
        }

        private Dictionary<int, int> MenuItemPopularityByDay(DateTime start, DateTime finish)
        {
           
                if (start > finish)
                    return null;
                else
                {
                    Dictionary<int, int> result = new Dictionary<int, int>();
                    foreach (RADB.DataSetRA.ProductsRow item in dataSetRA.Products.Rows)
                    {
                        result.Add(item.ID, 0);
                    }

                    foreach (RADB.DataSetRA.OrderItemsRow item in dataSetRA.OrderItems.Rows)
                    {
                        if (item.PlacingTime.Date >= start.Date && item.PlacingTime.Date <= finish.Date)
                        {
                            result[item.Product] += item.Quantity;
                        }
                    }

                    return result;
                }
            
        }

        private double[] TurnAroundTimeByDay(DateTime start, DateTime finish)
        {

                if (start > finish)
                    return null;
                else
                {
                    double[] result = new double[(finish.Date - start.Date).Days + 1];
                    int[] count = new int[(finish.Date - start.Date).Days + 1];
                    foreach (RADB.DataSetRA.SessionsRow item in dataSetRA.Sessions.Rows)
                    {
                        if (item.StartTime.Date >= start.Date && item.StartTime.Date <= finish.Date)
                        {
                            try
                            {
                                result[(item.StartTime.Date - start.Date).Days] += (item.FinishTime - item.StartTime).TotalMinutes;
                                count[(item.StartTime.Date - start.Date).Days]++;
                            }
                            catch (Exception)
                            {
                                //do nothing
                            }
                        }
                    }
                    for (int i = 0; i < result.Length; i++)
                        if (count[i] != 0)
                        {
                            result[i] /= count[i];    
                        }

                    return result;
                }
           
        }

        private double[] PreparationTimeByDay(DateTime start, DateTime finish)
        {
           
                if (start > finish)
                    return null;
                else
                {
                    double[] result = new double[(finish.Date - start.Date).Days + 1];
                    int[] count = new int[(finish.Date - start.Date).Days + 1];
                    foreach (RADB.DataSetRA.OrderItemsRow item in dataSetRA.OrderItems.Rows)
                    {
                        if (item.PlacingTime.Date >= start.Date && item.PlacingTime.Date <= finish.Date)
                        {
                            try
                            {
                                result[(item.PlacingTime.Date - start.Date).Days] += (item.FinishedTime - item.PlacingTime).Hours;
                                count[(item.PlacingTime.Date - start.Date).Days]++;
                            }
                            catch (Exception)
                            {
                                //do nothing
                                
                            }
                        }
                    }
                    for (int i = 0; i < result.Length; i++)
                        if (count[i] != 0)
                        {
                            result[i] /= count[i];
                        }
                    return result;
                }
            
        }

        //0: num of placing, 1: num of deliver
        private Dictionary<int, int[]> WaiterEffciency(DateTime start, DateTime finish)
        {
            if (start > finish)
                return null;
            else
            {
                if (dataSetRA.EmployeeRole.Select("RoleName = 'Waiter'").Length == 1)
                {
                    int waiter = ((RADB.DataSetRA.EmployeeRoleRow)dataSetRA.EmployeeRole.Select("RoleName = 'Waiter'")[0]).ID;
                    Dictionary<int, int[]> result = new Dictionary<int,int[]>();
                    foreach (RADB.DataSetRA.EmployeesRow item in dataSetRA.Employees)
                        if (item.Role == waiter)
                        {
                            result.Add(item.ID, new int[2]);
                        }
                    foreach (RADB.DataSetRA.OrderItemsRow item in dataSetRA.OrderItems.Rows)
                    {
                        if (item.PlacingTime.Date >= start.Date && item.PlacingTime.Date <= finish.Date)
                        {
                            try
                            {

                                result[item.DeliverWaiter][1]++;
                            }
                            catch (Exception)
                            {
                                //do nothing
                            }
                            try
                            {
                                result[item.PlacingWaiter][0]++;
                            }
                            catch (Exception)
                            {
                                //do nothing
                                
                            }
                        }
                    }
                    return result;
                }
                else
                {
                    return null;
                }
            }
        }

    }

}
